package maple.core;

import java.util.Date;
import java.util.HashMap;

import jade.lang.acl.ACLMessage;

import maple.lang.Command;
import maple.lang.Language;
import maple.util.Planner;
import maple.util.Task;
import maple.util.tasks.MasterTask;
import maple.util.Timestamp;

public abstract class ContextProvider extends Consumer
{
	public static enum State{ UNKNOWN };
	
	protected HashMap< String, String > _perceptions;

	public ContextProvider( final int number )
	{
		super( Language.Instruction.INTERPRET, number );

		_perceptions = new HashMap< String, String >();
	}

	protected void actionRequest( final ACLMessage message )
	{
		//_logger.info( message.getContent() );
		
		String content = message.getContent();

		String result = Command.Message.BAD_COMMAND.toString(); 
		Command command = new Command( content );
		if( command.isAvailable() )
		{
			switch( command.getInstruction() )
			{
				case INTERPRET:
					result = interpret( command );
			}
		}

		result = Timestamp.Default.format( new Date( System.currentTimeMillis() ) ) + Language.DELIMITER + result;

		HashMap< String, String > parameters = new HashMap< String, String >();
		parameters.put( Planner.Property.POSTCONDITION.toString(), _postcondition ); 
		parameters.put( Task.Property.COMMAND.toString(), content );
		String location = message.getUserDefinedParameter( MasterTask.Property.LOCATION.toString() );
		if( location != null )
		{
			parameters.put( MasterTask.Property.LOCATION.toString(), location );
		}
		
		sendMessage( ACLMessage.INFORM, message.getSender().getName(), result, parameters, null ); 
	}

	/**
	 * return the status of the specified command
	 *
	 * @param	command	the specified command
	 * @return	the status of the specified command
	 *
	 * @author	snowfoxy
	 * @since	2011-11-24
	 */
	protected String interpret( final Command command )
	{
		if( isValid( command ) )
		{
			return interpret();
		}
		return ContextProvider.State.UNKNOWN.toString();
	}

	/**
	 * return true if the specified command is valid
	 *
	 * @param	command	the specified command
	 * @return	true if the command is valid
	 *
	 * @author	snowfoxy
	 * @since	2011-11-15
	 */
	protected boolean isValid( final Command command )
	{
		for( String precondition : _preconditions )
		{
			String value = command.getParameter( precondition );
			if( value == null )
			{
				return false;
			}
			_perceptions.put( precondition, value );
		}
		return true;
	}

	/**
	 * return the String representation of the operator
	 *
	 * @return	the String representation of the operator
	 *
	 * @author	snowfoxy
	 * @since	2011-11-15
	 */
	protected String toOperator()
	{
		String operator = getName() + Language.DELIMITER + _operator;
		for( String precondition : _preconditions )
		{
			operator = operator 
				       + Language.DELIMITER
					   + precondition
					   + Language.ASSIGN
					   + Language.QUOTE
					   + "-1"
					   + Language.QUOTE;
		}
		return operator; 
	}

	protected abstract String interpret();
}
